package hehe.container.format;

import hehe.container.Container;
import hehe.container.definition.Ref;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类型转换入口
 *<B>说明：</B>
 *<pre>
 * 主要用于xml bean 的类型转
 * 从string 转换成其他类型
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  示例:常规用法
 *  formatValue = Format.invoke("int","100",field);
 *
 *
 * 新增其他类型转换器
 * 操作步骤
 * 1.创建类型转换器,继承DataFormat
 * 2.注册类型转换器
 *  ...java
 *  public class DateFormat extends DataFormat
     {
         public static Object parse(String value,Field field)
         {
            return Long.valueOf(value);
         }
     }
 *
 * 硬编码的形式注册类型转换器
 * formats.put("java.lang.date", "DateFormat");
 * formats.put("date", "DateFormat");
 *
 * 注解的方式注册类型
 * @Format(
    dataFormat="BooleanFormat",
    formatTypes={"java.lang.Boolean","boolean"},
    formatArgs={String.class,Field.class}
    )
 *  ...
 *
 *
 *
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class DataFormat
{
    /**
     * 基本类型对应的方法列表
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    private static final Map<String,String> formats = new HashMap<String,String>() {{}};

    /**
     * 类型转换方法的参数类型
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    private static final Map<String,Class[]> formatsArgs = new HashMap<String,Class[]>() {{}};

    /**
     * 当前包名
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    private static String packageName = "";

    static {
//        // 初始化静态变量
//        formats.put("java.lang.String", "StringFormat");
//        formats.put("String", "StringFormat");
//        formatsArgs.put("StringFormat",new Class[]{String.class,Field.class});
//
//        // int, integer, tinyint, smallint, mediumint
//        formats.put("java.lang.Integer", "IntFormat");
//        formats.put("int", "IntFormat");
//        formatsArgs.put("IntFormat",new Class[]{String.class,Field.class});
//
//        // bigint
//        formats.put("java.lang.Long", "LongFormat");
//        formats.put("long", "LongFormat");
//        formatsArgs.put("LongFormat",new Class[]{String.class,Field.class});
//
//        // real, double
//        formats.put("java.lang.Double", "DoubleFormat");
//        formats.put("double", "DoubleFormat");
//        formatsArgs.put("DoubleFormat",new Class[]{String.class,Field.class});
//
//        // float
//        formats.put("java.lang.Float", "FloatFormat");
//        formats.put("float", "FloatFormat");
//        formatsArgs.put("FloatFormat",new Class[]{String.class,Field.class});
//
//        // bit
//        formats.put("java.lang.Boolean", "BooleanFormat");
//        formats.put("boolean", "BooleanFormat");
//        formatsArgs.put("BooleanFormat",new Class[]{String.class,Field.class});
//
//        // date, year
//        formats.put("java.sql.Date", "DateFormat");
//        formatsArgs.put("DateFormat",new Class[]{String.class,Field.class});
//
//        // time
//        formats.put("java.sql.Time", "TimeFormat");
//        formatsArgs.put("TimeFormat",new Class[]{String.class,Field.class});
//
//        // timestamp, datetime
//        formats.put("java.sql.Timestamp", "TimestampFormat");
//        formatsArgs.put("TimestampFormat",new Class[]{String.class,Field.class});
//
//        // decimal, numeric
//        formats.put("java.math.BigDecimal", "BigDecimalFormat");
//        formatsArgs.put("BigDecimalFormat",new Class[]{String.class,Field.class});
//
//        // unsigned bigint
//        formats.put("java.math.BigInteger", "BigIntegerFormat");
//        formatsArgs.put("BigIntegerFormat",new Class[]{String.class,Field.class});
//
//        // binary, varbinary, tinyblob, blob, mediumblob, longblob
//        // qjd project: print_info.content varbinary(61800);
//        formats.put("[B", "toByte");
//
//        // unsigned bigint
//        formats.put("Map", "MapFormat");
//        formats.put("java.util.Map", "MapFormat");
//        formatsArgs.put("MapFormat",new Class[]{Map.class,Field.class});
//
//        // unsigned bigint
//        formats.put("List", "ListFormat");
//        formats.put("java.util.List", "ListFormat");
//        formatsArgs.put("ListFormat",new Class[]{List.class,Field.class});

        DataFormat.packageName = DataFormat.getPackageName();
    }

    /**
     * 注册类型转换器
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void registerFormat(String dataFormat,String[] formatTypes,Class[] formatArgs)
    {
        for (String formatType:formatTypes) {
            formats.put(formatType,dataFormat);
        }

        formatsArgs.put(dataFormat,formatArgs);
    }

    /**
     * 获取对应的类型转换类名称
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected static String getFormat(String fieldType)
    {
        return formats.get(fieldType);
    }

    /**
     * 强制类型转换
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param formatType 转换的类型
     * @param value　转换的值
     * @param field　字段
     * @return Object
     */
    public static Object invoke(String formatType, Object value, Field field) throws Exception
    {
        /*
        // 如果是ref 类, 则直接从容器读取
        if (value instanceof Ref) {
            return Container.getContainer().getBean(((Ref)value).getRef());
        }
        */

        String classType = DataFormat.getFormat(formatType);
        Class[] formatArgs  = formatsArgs.get(classType);
        // 如找不道对应类型,默认使用cast 转换类型
        if (classType == null) {
            Class <?> cls = Class.forName(formatType) ;
            return cls.cast(value);
        }

        // 如找".",则认为是一个完整的class 名
        if (classType.indexOf(".") <= -1) {
            classType = DataFormat.packageName + "." + classType;
        }

        Class <?> cls = Class.forName(classType) ;
        Object[] args = {value,field};
        Method ownerMethod = null;

        try {
            ownerMethod = cls.getMethod("parse",formatArgs);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return value;
        }

        return ownerMethod.invoke(null,args);
    }

    /**
     * 获取当前类包名
     *<B>说明：</B>
     *<pre>
     * 　略
     *</pre>
     * @return 当前包名
     */
    public static String getPackageName()
    {
        return new Object()    {
            public String getPackageName()
            {
                Class onwClass = this.getClass();
                Package dbPackage =  onwClass.getPackage();
                return  dbPackage.getName();
            }
        }.getPackageName();

    }


    public static Object parse(Object value)
    {
        return null;
    }
}
